<?php
namespace App\Admin;

use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

/**
 * 后台类
 */
class Admin
{
	const VERSION = '1.0.0';
	
	public static function user()
	{
		return static::guard()->user();
	}

	/**
	 * 获得后台用户组守卫
	 */
	public static function guard()
	{
		$guard_name = config('admin.guard_name') ?: 'admin';
		return Auth::guard($guard_name);
	}

	/**
	 * 这里注册后台登录注册等基础路由
	 */
	public static function routes()
	{
		// Route::apiSingleton('token', \App\Admin\Controllers\Auth\TokenController::class)->creatable()->only([
		// 	'store',
		// 	'destroy'
		// ]);

		// Token
		Route::get('/token', [\App\Admin\Controllers\Auth\TokenController::class, 'index']);
		Route::post('/token', [\App\Admin\Controllers\Auth\TokenController::class, 'store']);
		Route::delete('/token', [\App\Admin\Controllers\Auth\TokenController::class, 'destroy']);


		// 个人资料
		Route::get('/profile', [\App\Admin\Controllers\Auth\ProfileController::class, 'show']);
		// 修改个人资料
		Route::put('/profile', [\App\Admin\Controllers\Auth\ProfileController::class, 'update']);
		// 上传头像
		Route::post('/profile', [\App\Admin\Controllers\Auth\ProfileController::class, 'store']);
		// 修改密码
		Route::put('/profile/password', [\App\Admin\Controllers\Auth\ProfileController::class, 'password']);
		

		// google 2fa
		Route::controller(\App\Admin\Controllers\Auth\TwoFactorAuthenticationController::class)->group(function () {
		    Route::get('/two-factor-authentication', 'show');
		    Route::post('/two-factor-authentication', 'store');
		    Route::delete('/two-factor-authentication', 'destroy');
		});

		// oauth2 and oidc
		Route::controller(\App\Admin\Controllers\Auth\OAuthController::class)->group(function () {
		    Route::get('/oauth/providers', 'providers');
		    Route::get('/oauth/{name}/exchange', 'exchange');
		    Route::get('/oauth/{name}/redirect', 'redirect');
		});
	}

	public static function success($data=null, $code=0, $message='success')
	{
		return response([
			'code' => $code,
			'message' => $message,
			'data' => $data,
		]);
	}


	public static function getAuthorization($request=null)
	{
		$request = is_null($request) ? request() : $request ;

        $token = $request->header('Authorization');
        if( Str::startsWith($token, 'Bearer') ){
            $token = substr($token, 7);

        }else{
            $token = $request->header('X-Token', $request->input('api_token'));
        }

        if( !$token ){
        	return 'jrATliHXoFZYhAdgRneZKz3YB94uX2eXGViImEIRl22yFScqjMclO44VlD9G7oP6';
        }

        return $token;
	}

	/**
	 * 构建 OAuth2 驱动程序实例 (laravel/socialite)
	 * 基本等同于 Socialite::driver($name), 但是配置从admin.php读取，且默认使用无状态认证
	 * @link https://github.com/laravel/socialite
	 */
	public static function socialite($name)
	{
        // 读取配置
        $config = config('admin.oauth2');
        $providerConfig = Arr::get($config, $name);
        abort_unless($providerConfig, 500, "缺少配置:{$name}");

        // 读取
        $providerClass = Arr::get($providerConfig, 'class', "\Laravel\Socialite\Two\\".Str::studly($name)."Provider") ;
        abort_unless(class_exists($providerClass), 500, "{$name}未配置class，或class不存在{$providerClass}");

        $provider = \Laravel\Socialite\Facades\Socialite::buildProvider($providerClass, $providerConfig);
        return $provider->stateless();// 无状态认证
	}

	public static function flattenTree(array $elements) {
	    $rootTree = [];
	    $buildResult = function($parent_id, $level=0) use (&$rootTree, &$buildResult, $elements) {
	        foreach ($elements as $element) {
	            if ($element['parent_id'] == $parent_id) {
	                $newElement = $element;
	                if( $level!=0 ){
	                	$newElement["name"] = ' '.str_repeat('| ──── ', $level) . $newElement["name"];
	                }
	                $rootTree[] = $newElement;
	                $buildResult($element['id'], $level+1);
	            }
	        }
	    };
	    $buildResult(0);
	    return $rootTree;
	}


	/**
	 * IP转归属地
	 */
	public static function location(string $ipAdress, string $language='zh-CN'): string
	{
		if( in_array($ipAdress, ['127.0.0.1', '::1']) ){
			return '本机';
		}

		$isPrivateIP = function($ip) {
		    $ip = ip2long($ip);// 将IPv4地址转化为长整型
		    $privateIps = [
		        '10.0.0.0' => '10.255.255.255',
		        '172.16.0.0' => '172.31.255.255',
		        '192.168.0.0' => '192.168.255.255'
		    ];
		    
		    foreach ($privateIps as $start => $end) {
		        $start = ip2long($start);
		        $end = ip2long($end);
		        
		        if (($ip >= $start) && ($ip <= $end)) {
		            return true;
		        }
		    }
		    
		    // 对于IPv6，可以使用filter_var来检查地址是否以"fc00::/7"开始
		    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) && substr(inet_pton($ip), 0, 2) === "\xfc\x00") {
		        return true;
		    }

		    return false;
		};

		if( $isPrivateIP($ipAdress) ) {
			return '局域网';
		}

		try {
			$databaseFile = resource_path('GeoLite2-City.mmdb');
			if( !file_exists($databaseFile) ){
				return $ipAdress;
			}

			if( !class_exists(\GeoIp2\Database\Reader::class) ){
				return $ipAdress;
			}
			$cityDbReader = new \GeoIp2\Database\Reader($databaseFile);
			$record = $cityDbReader->city($ipAdress);

			$country  = Arr::get($record->country->names, $language);
			$province = Arr::get($record->mostSpecificSubdivision->names, $language);
			$city     = Arr::get($record->city->names, $language);

			return "{$country} {$province} {$city}";

		} catch (\Exception $e) {
			return $ipAdress;
		}
	}
}